import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../models/camera_models.dart';

/// 原生摄像头实现
///
/// 这是使用平台原生API的摄像头实现，提供最佳的性能和完全的控制能力。
/// iOS使用AVFoundation，Android使用CameraX/Camera2。
class NativeImplementation {
  static MultiCameraHostApi? _hostApi;
  static CameraConfig? _config;
  static bool _isInitialized = false;
  static CameraLensDirection _currentDirection = CameraLensDirection.back;
  static FlashMode _currentFlashMode = FlashMode.off;

  // 用于缓存Android端的纹理信息
  static CameraTexture? _cameraTexture;
  // 用于缓存正在进行的纹理创建Future，防止重复调用
  static Future<CameraTexture>? _textureFuture;

  /// 获取Host API实例
  static MultiCameraHostApi get _api {
    _hostApi ??= MultiCameraHostApi();
    return _hostApi!;
  }

  /// 检查原生实现是否可用
  static Future<bool> isAvailable() async {
    try {
      final result =
          await _api.isImplementationAvailable(CameraImplementationType.native);
      return result;
    } catch (e) {
      return false;
    }
  }

  /// 初始化摄像头
  static Future<void> initialize(CameraConfig config) async {
    if (_isInitialized) {
      await dispose();
    }

    try {
      _config = config;
      _currentDirection = config.lensDirection;

      await _api.initializeCamera(config, CameraImplementationType.native);
      _isInitialized = true;
    } catch (e) {
      throw CameraError(
        code: 'INITIALIZATION_FAILED',
        message: '原生摄像头初始化失败: ${e.toString()}',
      );
    }
  }

  /// 创建摄像头预览Widget
  static Widget buildPreview({
    required CameraPreviewConfig previewConfig,
    VoidCallback? onCameraReady,
    Function(CameraError)? onError,
  }) {
    if (!_isInitialized || _config == null) {
      debugPrint('❌ 原生摄像头未初始化，显示错误提示');
      return Container(
        color: Colors.black,
        child: const Center(
          child: Text(
            '原生摄像头未初始化',
            style: TextStyle(color: Colors.white),
          ),
        ),
      );
    }

    // iOS 平台使用之前的 UiKitView 实现
    if (Platform.isIOS) {
      return _buildIosPreview(previewConfig, onCameraReady, onError);
    }
    // Android 平台使用新的 Texture 实现
    else if (Platform.isAndroid) {
      return _buildAndroidPreview(previewConfig, onCameraReady, onError);
    }
    // 其他平台显示不支持
    else {
      return Container(
        color: Colors.black,
        child: const Center(
          child: Text('当前平台不支持原生摄像头', style: TextStyle(color: Colors.white)),
        ),
      );
    }
  }

  /// 为 Android 构建基于 Texture 的预览
  ///
  /// 这个方法解决了Android原生实现中的重大预览拉伸问题：
  ///
  /// 🚨 问题根源：
  /// 1. 相机传感器通常是横向的，输出如1920x1080的横向图像
  /// 2. Flutter UI会自动将图像旋转90度以适应竖屏显示
  /// 3. 但如果容器还使用原始的1920x1080比例，就会导致严重的拉伸变形
  ///
  /// ✅ 解决方案（参考flutter_camera插件的成功经验）：
  /// 1. 获取相机的原始分辨率（如：width=1920, height=1080）
  /// 2. 在创建显示容器时交换宽高（使用height作为width，width作为height）
  /// 3. 这样容器的比例就是1080x1920，完美匹配UI旋转后的显示
  /// 4. 使用FittedBox + BoxFit.cover确保正确缩放到目标尺寸
  ///
  /// 📊 效果对比：
  /// - 修复前：预览在方形容器中被拉伸，宽度过长、高度压缩约1/3
  /// - 修复后：预览比例完全正确，与iOS效果一致，无任何变形
  static Widget _buildAndroidPreview(
    CameraPreviewConfig previewConfig,
    VoidCallback? onCameraReady,
    Function(CameraError)? onError,
  ) {
    return FutureBuilder<CameraTexture>(
      // 关键修复：调用一个只创建一次Future的辅助方法
      future: _getAndroidTexture(onCameraReady, onError),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Container(
            width: previewConfig.width,
            height: previewConfig.height,
            color: Colors.black,
            child: const Center(child: CircularProgressIndicator()),
          );
        }

        if (snapshot.hasError ||
            !snapshot.hasData ||
            snapshot.data?.textureId == null) {
          return Container(
            width: previewConfig.width,
            height: previewConfig.height,
            color: Colors.black,
            child: const Center(
                child: Text('无法创建相机预览', style: TextStyle(color: Colors.white))),
          );
        }

        final textureData = snapshot.data!;
        debugPrint(
            '📐 NativeImplementation: 相机分辨率 = ${textureData.width}x${textureData.height}');

        Widget preview;

        // 应用尺寸配置
        if (previewConfig.width != null && previewConfig.height != null) {
          final targetWidth = previewConfig.width!;
          final targetHeight = previewConfig.height!;
          debugPrint(
              '📐 NativeImplementation: 目标尺寸 = ${targetWidth}x${targetHeight}');

          if (textureData.width == null || textureData.height == null) {
            return Container(
              color: Colors.black,
              child: const Center(
                  child:
                      Text('无法获取相机分辨率', style: TextStyle(color: Colors.white))),
            );
          }

          // 🔑 关键修正：交换宽高以匹配UI的纵向显示
          //
          // 这是解决Android预览拉伸问题的核心技术方案，直接借鉴了flutter_camera插件的成功经验：
          //
          // 📱 相机传感器的物理特性：
          // - 手机相机传感器通常是横向布局的（landscape orientation）
          // - 例如：传感器输出 1920x1080 (宽x高)
          //
          // 🔄 Flutter UI的自动处理：
          // - Flutter会自动将相机图像旋转90度以适应竖屏UI
          // - 旋转后的视觉效果是 1080x1920 (宽x高)
          //
          // ⚠️ 问题所在：
          // - 如果我们的容器还使用原始尺寸 1920x1080，就会出现严重的宽高比不匹配
          // - 导致图像被强制拉伸以填充容器，产生"宽度过长、高度压缩"的变形
          //
          // ✅ 解决方案：
          // - 我们在Dart层面手动交换宽高数据
          // - 容器使用 1080x1920 的比例，完美匹配UI旋转后的实际显示
          // - 这样FittedBox就能正确地缩放图像，不会产生任何拉伸变形
          preview = SizedBox(
            width: targetWidth,
            height: targetHeight,
            child: ClipRect(
              child: FittedBox(
                fit: BoxFit.cover,
                child: SizedBox(
                  // 💡 核心逻辑：宽高交换！
                  //
                  // 原始相机数据：width=1920, height=1080 (横向)
                  // 交换后的容器：width=1080, height=1920 (竖向)
                  //
                  // 这确保了容器的宽高比与UI旋转后的图像宽高比完全一致
                  width: textureData.height!, // 使用相机的height作为容器的width
                  height: textureData.width!, // 使用相机的width作为容器的height
                  child: Texture(textureId: textureData.textureId!),
                ),
              ),
            ),
          );
        } else {
          // 没有指定尺寸时，直接使用 Texture
          // 注意：这种情况下可能仍然会有轻微的比例问题，建议总是指定尺寸
          preview = Texture(textureId: textureData.textureId!);
        }

        // 使用SizedBox和Clip/Container来应用所有布局和装饰
        return _applyPreviewDecorations(preview, previewConfig);
      },
    );
  }

  /// 辅助方法，用于获取或创建Android纹理的Future
  static Future<CameraTexture> _getAndroidTexture(
      VoidCallback? onCameraReady, Function(CameraError)? onError) {
    if (_textureFuture != null) {
      // Future已经存在，直接返回它
      return _textureFuture!;
    }
    // Future不存在，创建它，并将其缓存起来
    _textureFuture = _createAndCacheAndroidTexture(onCameraReady, onError);
    return _textureFuture!;
  }

  /// 清除Android纹理缓存
  ///
  /// 当摄像头切换时调用，确保下次预览时使用新的纹理连接到新的摄像头
  static void _clearAndroidTextureCache() {
    debugPrint('🗑️ 清除Android纹理缓存');
    _cameraTexture = null;
    _textureFuture = null;
  }

  /// 实际创建并缓存纹理的私有方法
  static Future<CameraTexture> _createAndCacheAndroidTexture(
      VoidCallback? onCameraReady, Function(CameraError)? onError) async {
    try {
      final texture = await _api.createCameraTexture();
      _cameraTexture = texture; // 缓存结果
      if (onCameraReady != null) {
        WidgetsBinding.instance.addPostFrameCallback((_) => onCameraReady());
      }
      return texture;
    } catch (e) {
      // 如果创建失败，清除Future以便下次可以重试
      _textureFuture = null;
      final error =
          CameraError(code: 'TEXTURE_CREATION_FAILED', message: e.toString());
      if (onError != null) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          onError(error);
        });
      }
      rethrow;
    }
  }

  /// 为 iOS 构建基于 PlatformView 的预览
  static Widget _buildIosPreview(
    CameraPreviewConfig previewConfig,
    VoidCallback? onCameraReady,
    Function(CameraError)? onError,
  ) {
    final creationParams = _buildCreationParams(previewConfig);
    Widget preview = UiKitView(
      viewType: 'multi_camera_preview',
      creationParams: creationParams,
      creationParamsCodec: const StandardMessageCodec(),
      onPlatformViewCreated: (int id) {
        debugPrint('✅ UiKitView创建完成，ID: $id');
        Future.delayed(const Duration(milliseconds: 100), () {
          onCameraReady?.call();
        });
      },
    );
    return _applyPreviewDecorations(preview, previewConfig);
  }

  /// 将预览装饰（尺寸、形状、边框）应用于给定的预览Widget
  static Widget _applyPreviewDecorations(
      Widget preview, CameraPreviewConfig previewConfig) {
    Widget decoratedPreview = preview;

    // 裁剪形状
    if (previewConfig.isCircular) {
      decoratedPreview = ClipOval(child: decoratedPreview);
    } else if (previewConfig.borderRadius > 0) {
      decoratedPreview = ClipRRect(
        borderRadius: BorderRadius.circular(previewConfig.borderRadius),
        child: decoratedPreview,
      );
    }

    // 添加边框（在裁剪之后，所以边框也会被裁剪）
    if (previewConfig.showBorder) {
      decoratedPreview = Container(
        decoration: BoxDecoration(
          border: Border.all(
            color: Color(previewConfig.borderColor ?? 0xFFFFFFFF),
            width: previewConfig.borderWidth,
          ),
          shape:
              previewConfig.isCircular ? BoxShape.circle : BoxShape.rectangle,
          borderRadius: previewConfig.isCircular
              ? null
              : BorderRadius.circular(previewConfig.borderRadius),
        ),
        child: decoratedPreview,
      );
    }

    // 应用最终尺寸
    if (previewConfig.width != null && previewConfig.height != null) {
      return SizedBox(
        width: previewConfig.width,
        height: previewConfig.height,
        // ClipOval/ClipRRect需要一个有限制的父组件才能工作
        child: decoratedPreview,
      );
    }

    return decoratedPreview;
  }

  /// 拍照
  static Future<CaptureResult> takePicture() async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      final result = await _api.takePicture();
      return result;
    } catch (e) {
      throw CameraError(
        code: 'CAPTURE_FAILED',
        message: '原生摄像头拍照失败: ${e.toString()}',
      );
    }
  }

  /// 切换摄像头方向
  static Future<void> switchCamera(CameraLensDirection direction) async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      // 🔧 修复Android摄像头切换卡住问题
      //
      // 问题根源：
      // 当切换摄像头时，Android端的NativeCameraManager会重新绑定CameraX用例，
      // 但Flutter端缓存的纹理和Surface Provider仍然连接到旧的摄像头实例，
      // 导致预览流无法更新，出现"卡住"现象。
      //
      // 解决方案：
      // 在切换摄像头之前，清除Flutter端的纹理缓存，
      // 这样下次调用buildPreview时会重新创建纹理，连接到新的摄像头。
      if (Platform.isAndroid) {
        debugPrint('🔄 Android摄像头切换：清除纹理缓存以避免预览卡住');
        _clearAndroidTextureCache();
      }

      await _api.switchCamera(direction);
      _currentDirection = direction;

      debugPrint('✅ 摄像头已切换到: ${direction.name}');
    } catch (e) {
      throw CameraError(
        code: 'SWITCH_FAILED',
        message: '原生摄像头切换失败: ${e.toString()}',
      );
    }
  }

  /// 设置闪光灯模式
  static Future<void> setFlashMode(FlashMode mode) async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      await _api.setFlashMode(mode);
      _currentFlashMode = mode;
    } catch (e) {
      throw CameraError(
        code: 'FLASH_MODE_FAILED',
        message: '设置原生摄像头闪光灯模式失败: ${e.toString()}',
      );
    }
  }

  /// 开始预览
  static Future<void> startPreview() async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      await _api.startPreview();
    } catch (e) {
      throw CameraError(
        code: 'START_PREVIEW_FAILED',
        message: '启动原生摄像头预览失败: ${e.toString()}',
      );
    }
  }

  /// 停止预览
  static Future<void> stopPreview() async {
    if (!_isInitialized) {
      return; // 如果未初始化，直接返回
    }

    try {
      await _api.stopPreview();
    } catch (e) {
      // 停止预览失败不抛出异常，只记录日志
      debugPrint('停止原生摄像头预览失败: ${e.toString()}');
    }
  }

  /// 释放资源
  static Future<void> dispose() async {
    try {
      await _api.dispose();
    } catch (e) {
      debugPrint('释放原生摄像头资源失败: ${e.toString()}');
    } finally {
      _config = null;
      _isInitialized = false;
      // 清理Flutter端的纹理缓存
      _cameraTexture = null;
      _textureFuture = null;
    }
  }

  /// 暂停摄像头session
  static Future<void> pauseSession() async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      await _api.pauseSession();
    } catch (e) {
      throw CameraError(
        code: 'PAUSE_SESSION_FAILED',
        message: '暂停原生摄像头session失败: ${e.toString()}',
      );
    }
  }

  /// 恢复摄像头session
  static Future<void> resumeSession() async {
    if (!_isInitialized) {
      throw CameraError(
        code: 'NOT_INITIALIZED',
        message: '原生摄像头未初始化',
      );
    }

    try {
      await _api.resumeSession();
    } catch (e) {
      throw CameraError(
        code: 'RESUME_SESSION_FAILED',
        message: '恢复原生摄像头session失败: ${e.toString()}',
      );
    }
  }

  /// 获取摄像头能力信息
  static Future<CameraCapabilities> getCameraCapabilities() async {
    try {
      return await _api.getCameraCapabilities();
    } catch (e) {
      throw CameraError(
        code: 'GET_CAPABILITIES_FAILED',
        message: '获取原生摄像头能力信息失败: ${e.toString()}',
      );
    }
  }

  /// 获取当前摄像头方向
  static CameraLensDirection get currentDirection => _currentDirection;

  /// 获取当前闪光灯模式
  static FlashMode get currentFlashMode => _currentFlashMode;

  /// 是否已初始化
  static bool get isInitialized => _isInitialized;

  /// 构建平台视图创建参数
  static Map<String, dynamic> _buildCreationParams(CameraPreviewConfig config) {
    return {
      'width': config.width,
      'height': config.height,
      'isCircular': config.isCircular,
      'isSquare': config.isSquare,
      'borderRadius': config.borderRadius,
      'showBorder': config.showBorder,
      'borderColor': config.borderColor,
      'borderWidth': config.borderWidth,
    };
  }
}
